#include <windows.h>
#include <extend.h>

#define FS_PUBLIC 0
#define FS_STATIC 1
#define FS_INIT   2
#define FS_EXIT   3

typedef void ( * PFUNC )( void );

void StackInit( void );
void StackFree( void );
void _pushsym( PSYMBOL );
void _do( WORD wParams );
void NewDynSym( PSYMBOL );
PDYNSYM GetDynSym( LPSTR szSymName );
void LogSymbols( void );

extern PCLIPVAR _tos;

extern BOOL bError;

static PSYMBOL pStart = 0;

//----------------------------------------------------------------------------//

void Quit( void )
{
   StackFree();
   ExitProcess( 0 );
}

//----------------------------------------------------------------------------//

static void InitSymbols( PSYMBOL pSym )
{
   // First function symbol to start the application
   if( ! pStart && pSym->bScope == FS_PUBLIC && pSym->pVoid != 0 )
      pStart = pSym;

   if( pSym->bScope == FS_PUBLIC ) // main starting symbol
      NewDynSym( pSym );
}

//----------------------------------------------------------------------------//

static void InitStatics( PSYMBOL pSym )
{
   // initialize static variables and execute init procedures
   if( pSym->bScope == FS_INIT )
   {
      _pushsym( pSym );
      _PutNil();
      _do( 0 );
   }
}

//----------------------------------------------------------------------------//

static void ExitFunctions( PSYMBOL pSym )
{
   if( pSym->bScope == FS_EXIT )
   {
      _pushsym( pSym );
      _PutNil();
      _do( 0 );
   }
}

//----------------------------------------------------------------------------//

void main( void )
{
   StackInit();
   _ferase( "info.log" );

   _weed_eatr( InitSymbols );    // initializes the dynamic symbol table
   _weed_eatr( InitStatics );    // executes init functions and init statics

   _pushsym( pStart );           // Call the first declared public function
   ( _tos - 1 )->pbase = 0;      // no base call for this function call
   _PutNil();                    // places nil as self
   _do( 0 );

   _weed_eatr( ExitFunctions );  // executes exit functions
   LogSymbols();                 // debugs the dynamic symbol table
   Quit();
}

//----------------------------------------------------------------------------//

CLIPPER QUIT()
{
   bError = TRUE;
   // Quit();
}

//----------------------------------------------------------------------------//
